﻿Imports System.ComponentModel
Imports System.Net
Imports System.Net.Sockets

Public Class TcpClient
    Inherits System.ComponentModel.Component

#Region "variable"
    Private m_TcpClient As System.Net.Sockets.TcpClient = Nothing
    Private m_NetworkStream As NetworkStream = Nothing
    Private m_Data() As Byte = Nothing
#End Region

#Region "property"

    Private m_SerIP As String = "127.0.0.1"
    <DefaultValue(GetType(System.String), "127.0.0.1")> _
    Public Property SerIP() As String
        Get
            Return m_SerIP
        End Get
        Set(ByVal value As String)
            m_SerIP = value
        End Set
    End Property

    Private m_SerPort As Integer = 9999
    <DefaultValue(GetType(System.Int32), "9999")> _
    Public Property SerPort() As Integer
        Get
            Return m_SerPort
        End Get
        Set(ByVal value As Integer)
            m_SerPort = value
        End Set
    End Property

    Private m_BufferSize As Long = 8 * 1024     '8K
    Public Property BufferSize() As Long
        Get
            Return m_BufferSize
        End Get
        Set(ByVal value As Long)
            m_BufferSize = value
        End Set
    End Property

    Private m_Active As Boolean = False
    Public Property Active() As Boolean
        Get
            Return m_Active
        End Get
        Set(ByVal value As Boolean)
            m_Active = value
        End Set
    End Property

#End Region

#Region "constructed function"

    Public Sub New()
        Me.m_TcpClient = New System.Net.Sockets.TcpClient()
        Me.m_Data = New Byte(Me.m_BufferSize) {}
    End Sub

    Public Sub New(ByVal serIP As String, ByVal serPort As Integer)
        Me.m_SerIP = serIP
        Me.m_SerPort = serPort
        Me.m_TcpClient = New System.Net.Sockets.TcpClient()
        Me.m_Data = New Byte(Me.m_BufferSize) {}
    End Sub

#End Region

#Region "delegate"

#End Region

#Region "events"
    ''' <summary>
    ''' 建立连接事件
    ''' </summary>
    ''' <remarks></remarks>
    Public Event Connect As ConnectEventHandler
    Public Overridable Sub OnConnect(ByVal e As ConnectEventArgs)
        If e IsNot Nothing Then
            RaiseEvent Connect(Me, e)
        End If
    End Sub

    ''' <summary>
    ''' 数据到达事件
    ''' </summary>
    ''' <remarks></remarks>
    Public Event DataArrivaled As DataArrivaledEventHandler
    Public Overridable Sub OnDataArrivaled(ByVal e As DataArrivaledEventArgs)
        If e IsNot Nothing Then
            RaiseEvent DataArrivaled(Me, e)
        End If
    End Sub
#End Region

#Region "private method"

    ''' <summary>
    ''' 开始连接
    ''' </summary>
    Private Sub beginConnect()
        Me.m_TcpClient.BeginConnect(Me.m_SerIP, Me.m_SerPort, New AsyncCallback(AddressOf Me.doBeginConnect), Me.m_TcpClient)
    End Sub

    ''' <summary>
    ''' 接受连接委托方法
    ''' </summary>
    ''' <param name="ar"></param>
    ''' <remarks></remarks>
    Private Sub doBeginConnect(ByVal ar As IAsyncResult)
        Dim _TcpClient As Sockets.TcpClient = DirectCast(ar.AsyncState, Sockets.TcpClient)

        Try
            _TcpClient.EndConnect(ar)
            Me.m_NetworkStream = _TcpClient.GetStream()
            Me.OnConnect(New ConnectEventArgs(Nothing, False, Nothing))

            Me.m_NetworkStream.BeginRead(Me.m_Data, 0, Me.m_Data.Length, New AsyncCallback(AddressOf Me.beginReceiveData), Me.m_NetworkStream)
        Catch ex As Exception
            Me.OnConnect(New ConnectEventArgs(ex, True, Nothing))
        End Try
    End Sub

    ''' <summary>
    ''' 接受数据
    ''' </summary>
    ''' <param name="ar"></param>
    ''' <remarks></remarks>
    Private Sub beginReceiveData(ByVal ar As IAsyncResult)
        Dim _NetworkStream As NetworkStream = Nothing
        Dim _Length As Integer = 0

        Try
            _NetworkStream = DirectCast(ar.AsyncState, NetworkStream)
            _Length = _NetworkStream.EndRead(ar)

            Me.OnDataArrivaled(New DataArrivaledEventArgs(Me.m_Data, Nothing, False, Nothing))

            _NetworkStream.BeginRead(Me.m_Data, 0, Me.m_Data.Length, New AsyncCallback(AddressOf Me.beginReceiveData), _NetworkStream)
        Catch ex As Exception
            Throw ex
        End Try
    End Sub

#End Region

#Region "public method"

    ''' <summary>
    ''' 开始监听端口
    ''' </summary>
    Public Sub [Start]()
        Me.m_Active = True

        Me.beginConnect()
    End Sub

    ''' <summary>
    ''' 停止监听
    ''' </summary>
    Public Sub [Stop]()
        Me.m_Active = False

        'Me.m_TcpClient.Close()
    End Sub

    ''' <summary>
    ''' 发送数据
    ''' </summary>
    ''' <param name="data"></param>
    Public Sub Send(ByVal data() As Byte)
        If Me.m_NetworkStream IsNot Nothing Then
            Me.m_NetworkStream.Write(data, 0, data.Length)
        End If
    End Sub


#End Region

End Class
